package com.spring.sd;

import com.spring.sd.component.Component1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.Locale;

/**
 * ApplicationContext 除了继承 BeanFactory 外，还继承了：<br/>
 *
 * MessageSource：使其具备处理国际化资源的能力 <br/>
 * ResourcePatternResolver：使其具备使用通配符进行资源匹配的能力 <br/>
 * EnvironmentCapable：使其具备读取 Spring 环境信息、配置文件信息的能力 <br/>
 * ApplicationEventPublisher：使其具备发布事件的能力 <br/>
 *
 */
@Slf4j
//@SpringBootApplication
public class ContextApplication {
    public static void main(String[] args) throws Exception {
        test4(args);

    }


    /**
     * MessageSource：使其具备处理国际化资源的能力
     */
    private static void test1(String[] args) {
        // 在 SpringBoot 项目的 resources 目录下创建 messages.properties、
        // messages_en.properties、messages_zh_CN.properties、messages_zh_TW.properties
        // 四个国际化文件，除 messages.properties：
        //ConfigurableApplicationContext context = SpringApplication.run(ContextApplication.class, args);

        GenericApplicationContext context = new GenericApplicationContext();

        // 国际化资源由 ResourceBundleMessageSource 进行处理，使用 “干净” 的 Spring 容器 GenericApplicationContext，并添加对应的 Bean：
        context.registerBean("messageSource", MessageSource.class, () -> {
            ResourceBundleMessageSource ms = new ResourceBundleMessageSource();
            // 设置编码格式
            ms.setDefaultEncoding("utf-8");
            // 设置国际化资源文件的 basename
            ms.setBasename("messages");
            return ms;
        });

        context.refresh();

        // 不起作用输出的还是乱码
        System.out.println(context.getMessage("thanks", null, Locale.ENGLISH));
        System.out.println(context.getMessage("thanks", null, Locale.SIMPLIFIED_CHINESE));
        System.out.println(context.getMessage("thanks", null, Locale.TRADITIONAL_CHINESE));

        context.close();

    }

    /**
     * ResourcePatternResolver：使其具备使用通配符进行资源匹配的能力
     */
    private static void test2(String[] args) throws IOException {
        ConfigurableApplicationContext context = SpringApplication.run(ContextApplication.class, args);
        // --snip--

        Resource[] resources = context.getResources("classpath:application.properties");
        Assert.isTrue(resources.length > 0, "加载类路径下的 application.properties 文件失败");

        System.out.println(resources);

        // 使用 classpath* 可以加载 jar 里类路径下的 resource
        resources = context.getResources("classpath*:META-INF/spring.factories");
        Assert.isTrue(resources.length > 0, "加载类路径下的 META-INF/spring.factories 文件失败");
        context.close();
    }

    /**
     * EnvironmentCapable 的使用
     * java_home 是从环境变量中读取，properties.name 则是从 application.yml 配置文件中读取。
     */
    public static void test3(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(ContextApplication.class, args);

        System.out.println(context.getEnvironment().getProperty("java_home"));
        System.out.println(context.getEnvironment().getProperty("properties.name"));
        context.close();
    }


    /**
     * ApplicationEventPublisher 的使用
     * @param args
     */
    public static void test4(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(ContextApplication.class, args);

        Component1 component1 = context.getBean(Component1.class);
        component1.register();

        context.close();
    }
}
